package com.cpkso.taobao.taobao11client;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileWriter;
import java.io.IOException;
import java.nio.charset.Charset;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.Random;
import java.util.concurrent.atomic.AtomicBoolean;

import javax.swing.JButton;

import org.apache.http.HttpEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.json.JSONArray;
import org.json.JSONObject;

import com.teamdev.jxbrowser.chromium.Browser;
import com.teamdev.jxbrowser.chromium.LoadURLParams;
import com.teamdev.jxbrowser.chromium.dom.By;
import com.teamdev.jxbrowser.chromium.events.FinishLoadingEvent;
import com.teamdev.jxbrowser.chromium.events.LoadAdapter;
import com.teamdev.jxbrowser.chromium.swing.BrowserView;

/**
 * @author wrzhxy@qq.com
 * @date 2018年5月5日
 * 卖家客户端
 */
public class SellerClient {
	private final static int PAGE_SIZE = 15; 		// 每个请求获取最大500条数据
	// SUCCESS PAID
	private final static String AUTH_VERIFY = "https://trade.taobao.com/trade/security/auth_user_info.htm";
	private final static String ORDER_LIST = "https://trade.taobao.com/trade/itemlist/list_sold_items.htm";
	private final static String TIP = "https://trade.taobao.com/trade/json/memoInfo.htm?user_type=seller&_input_charset=utf-8&orderid=";
	// 120.27.39.105:9090/user/all
	final static String SELLER_URL = "http://120.27.39.105:9090/order/s";
//	private final static String SELLER_URL = "http://localhost:9090/order/s";
	private static String username = null;
	private static String path = null;
    
    // 卖家号
    public static void seller(String username, String path) {
    	// initial
    	SellerClient.username = username;
    	SellerClient.path = path;
		List<TbSBOrderVo> orders = new ArrayList<>();
		List<String> curstatus = new ArrayList<>();
		curstatus.add("PAID");
		// 浏览器对象
        Browser browser = new Browser();
        BrowserView view = new BrowserView(browser);
        
        // 设置获取订单的时间
        final JButton getOrderBtn = new JButton();
        // 设置按钮触发事件
        getOrderBtn.addActionListener(new ActionListener() {
        	
        	@Override
        	public void actionPerformed(ActionEvent e) {
        		// 在发送请求json数据的请求之前，先发送这个请求确认权限校验通过
        		browser.loadURL(AUTH_VERIFY);
        		App.sleep();
            	// 根据订单时间判断是否从当前时间往前推一个月的 - 不必，因为发送的请求带有筛选条件
            	// 获取当前时间
            	Date now = new Date();
            	long nowLong = now.getTime();
System.out.println("---now:" + new Date(nowLong));            	
            	// 2018-01-21 15:01:14
            	// 一个月以前
            	long oneMonthAgoLong = getOneMonthAgo(now);
            	
            	// 页码，如果头500不够就翻页
            	int pageNo = 1;
            	List<Integer> pageNoStore = new ArrayList<>();
            	pageNoStore.add(pageNo);
            	// 发送请求获取信息
            	sendAsncRequest(browser, oneMonthAgoLong, nowLong, pageNo, PAGE_SIZE, curstatus.get(0));
            	Random random = new Random();
            	// 当请求的页面加载完毕时触发本方法 获取订单信息
            	browser.addLoadListener(new LoadAdapter() {

					@Override
                    public void onFinishLoadingFrame(FinishLoadingEvent event) {
                        if (event.isMainFrame()) {
                        	// 页面加载完成后等一下再发送搜索请求
                        	int rand = random.nextInt() % 2 + 2;
                        	for (int i = 0; i < rand; i++) {
                        		App.sleep();
                        	}
                        	
                        	String strUndealData = browser.getDocument().getDocumentElement().findElement(By.tagName("body")).getInnerHTML();
//System.out.println("获取到的未处理：" + strUndealData);
                    		// 封装进json object
                    		JSONObject jsonUndealData = new JSONObject(strUndealData);
                    		// 获取mainOrders
                    		JSONArray mainOrders = jsonUndealData.getJSONArray("mainOrders");
System.out.println(mainOrders);                    		
                    		// 判断mainOrders是否为空[]
                    		// 获取一个月的订单
                    		// 判断时间
                    		// 如果没有取完，就翻页
                    		// 遍历 获取数据
                    		for (int i = 0; i < mainOrders.length(); i++) {
                    			TbSBOrderVo order = generateOrder(mainOrders, i);
System.out.println(":" + pageNoStore.get(0) + "-" + new Date(order.getOrderTime()) + "-" + order);
                    		    orders.add(order);
                    		}
                    		// 判断最后一条记录是不是第500，如果是继续翻页
                            if (mainOrders.length() >= PAGE_SIZE) {
                            	App.sleep();
                            	// 加个变量判断是交易成功还是买家已付款
                            	nextPage(browser, pageNoStore, oneMonthAgoLong, nowLong, curstatus.get(0));
                            } else {
                            	// 说明已经获取完毕
                            	// 将数据全部发送出去
System.out.println("\n\n\n------------------------------------------curstatus" + curstatus.get(0));

                            	if (!curstatus.get(0).equals("SUCCESS")) {
System.out.println("\n\n\n--------------------------------------------");                            		
									if (curstatus.get(0).equals("PAID")) {
										curstatus.set(0, "SEND");
									} else {
										curstatus.set(0, "SUCCESS");
									}
                            		pageNoStore.set(0, 0);
                            		nextPage(browser, pageNoStore, oneMonthAgoLong, nowLong, curstatus.get(0));
                            	} else {
                            		orders.sort(new OrderComparator());
                            		sendData(orders, SELLER_URL, username);
                            		browser.executeJavaScript("alert(\"获取数据成功!\");");
                            	}
                            }
                    		
                        } // end if
                    } // end method

                });
        	}
        	
        	/**
        	 * 将订单数据发送出去
        	 */
        	// 用户名
        	public void sendData(List<TbSBOrderVo> orders, String url, String username) {
        		CloseableHttpClient httpclient = HttpClients.createDefault();
        		// 发送Post请求
        		HttpPost httpPost = new HttpPost(url);
        		// 模拟json数据
        		JSONArray js = new JSONArray(orders);
//System.out.println("最终json数据：" + js.toString());
        		// 将Json数据放入StringEntity作为载体给httpPost来发送，所有数据要发送都要放入各种HttpClient定义的Entity实例中
        		StringEntity se = null;
    			se = new StringEntity(js.toString(), Charset.forName("UTF-8"));
        		se.setContentEncoding("UTF-8");
        		se.setContentType("application/json");
//        		httpPost.addHeader("Content-type", "application/json;charset=utf-8");
//        		httpPost.addHeader("Accept", "application/json");
        		httpPost.setEntity(se);
        		// 开始发送请求并拿到响应
        		CloseableHttpResponse response = null;
        		try {
        			response = httpclient.execute(httpPost);
        		} catch (IOException e) {
        			e.printStackTrace();
        		}
        		
        		try {
	    			// 打印状态码
//System.out.println("状态码：" + response.getStatusLine());
        			System.out.println("发送成功:" + js.length());
	    			// 
	    			HttpEntity entity = response.getEntity();
	    			// do something useful with the response body
	    			// and ensure it is fully consumed
	    			EntityUtils.consume(entity);
	    		} catch (IOException e) {
	    			e.printStackTrace();
	    		} finally {
	    			try {
	    				response.close();
	    			} catch (IOException e) {
	    				e.printStackTrace();
	    			}
	    		}
        	}
        	
        });
        
        App.initalFrame(view, getOrderBtn, "卖家号客户端");
        
        // 加载订单列表页
        // 开始时是登录页，登录后跳转订单列表页
        browser.loadURL(ORDER_LIST);
    }
    static private AtomicBoolean wait = new AtomicBoolean(false);
    static public TbSBOrderVo generateOrder(JSONArray mainOrders, int i) {
    	synchronized (wait) {
    		// 提取订单内容
    		JSONObject orderDetail = mainOrders.optJSONObject(i);
    		JSONObject orderInfo = orderDetail.getJSONObject("orderInfo");
    		// 下单时间
    		String createTimeStr = orderInfo.getString("createTime");
    		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    		Date createTime = null;
    		try {
    			createTime = sdf.parse(createTimeStr);
    		} catch (ParseException e) {
    			e.printStackTrace();
    		}
    		
    		// 订单id
    		String id = orderInfo.getString("id");
    		
    		// 订单金额
    		JSONObject payInfo = orderDetail.getJSONObject("payInfo");
    		Double actualFee = payInfo.getDouble("actualFee");
    		
    		// 产品名
    		// 子订单 包括运费险
    		JSONArray subOrder = orderDetail.getJSONArray("subOrders");
    		List<String> items = new ArrayList<>();
    		for (int j = 0; j < subOrder.length(); j++) {
    			JSONObject singleSubOrder = subOrder.optJSONObject(j);
    			JSONObject subItemInfo = singleSubOrder.getJSONObject("itemInfo");
    			String title = subItemInfo.getString("title");
    			items.add(title);
    		}
    		
    		TbSBOrderVo order = new TbSBOrderVo(id, "", createTime.getTime(), actualFee, items, username);
    		// 获取卖家订单关联的买家订单号
    		// 发送请求获取订单号
    		// {"tip":"113477339052415029"}
    		// 获取到cookie，用别的发送请求（不用jxbrowser）
    		Browser tip = new Browser();
    		tip.loadURL(TIP + id);
    		
    		tip.addLoadListener(new LoadAdapter() {
    			
    			@Override
    			public void onFinishLoadingFrame(FinishLoadingEvent event) {
    				synchronized (wait) {
    					// TODO 判断内容是否正确
    					String strUndealData = tip.getDocument().getDocumentElement().findElement(By.tagName("pre")).getInnerHTML();
    					// System.out.println("获取到的未处理：" + strUndealData);
    					// 封装进json object
    					getTip(path, order, strUndealData);
    					// 唤醒
    					wait.notify();
    				}
    			}
    			
    		});
    		// 阻塞
    		try {
    			wait.wait();
    		} catch (InterruptedException e) {
    			e.printStackTrace();
    		}
    		return order;
    	}
    }
    static public void nextPage(Browser browser, List<Integer> pageNoStore, Long oneMonthAgoLong, Long nowLong, String status) {
    	// 继续翻页
    	Integer pageNo = pageNoStore.get(0);
    	pageNo++;
    	pageNoStore.set(0, pageNo);
    	sendAsncRequest(browser, oneMonthAgoLong, nowLong, pageNo, PAGE_SIZE, status);
    }
    // 发送异步请求获取订单数据
    static public void sendAsncRequest(Browser browser, long beginDate, long endDate, int pageNo, int pageSize, String status) {
    	System.out.println("status:" + status);
    	browser.loadURL(new LoadURLParams("https://trade.taobao.com/trade/itemlist/asyncSold.htm?event_submit_do_query=1&_input_charset=utf8",
    			"action=itemlist/SoldQueryAction"
    					+ "&auctionType=0"
    					+ "&close=0"
    					+ "&dateBegin=" + beginDate
    					+ "&dateEnd=" + endDate
    					+ "&errorCheckcode=false"
    					+ "&orderStatus=" + status
    					+ "&pageNum=" + pageNo
    					+ "&pageSize=" + pageSize
    					+ "&prePageNo=1"
    					+ "&queryMore=false"
    					+ "&rxAuditFlag=0"
    					+ "&rxHasSendFlag=0"
    					+ "&rxOldFlag=0"
    					+ "&rxSendFlag=0"
    					+ "&rxSuccessflag=0"
    					+ "&tradeTag=0"
    					+ "&useCheckcode=false"
    					+ "&useOrderInfo=false",
    					"Accept:application/json, text/javascript, */*; q=0.01\n"
    							+ "Accept-Encoding: gzip, deflate, br\n"
    							+ "Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2\n"
    							+ "Content-Type:application/x-www-form-urlencoded; charset=UTF-8\n"
    							+ "Connection: keep-alive\n"
    							+ "Origin: https://trade.taobao.com\n"
    							+ "Referer: https://trade.taobao.com/trade/itemlist/list_sold_items.htm\n"
    							+ "Save-Data: on\n"
    							+ "User-Agent:Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.113 Safari/537.36"));
    }

	public static void getTip(String path, TbSBOrderVo order, String strUndealData) {
		JSONObject tipJson = new JSONObject(strUndealData);
		String buyerId = tipJson.getString("tip");
		if (buyerId != null && buyerId.matches("^[0-9]+")) {
			order.setBuyerId(buyerId.trim());
		} else {
			System.out.println("您的订单：" + order.getOrderId() + " " + order.getItems() + "无备注");
			BufferedWriter br = null;
			try {
				File file = new File(path + "/tip.txt");
				if (!file.exists()) file.createNewFile();
				br = new BufferedWriter(new FileWriter(file, true));
				SimpleDateFormat logFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
				String logDate = logFormat.format(new Date());
				br.write("无备注：" + logDate + " - " + order.getOrderId() + " " + order.getItems());
				br.newLine();
			} catch (FileNotFoundException e) {
				e.printStackTrace();
			} catch (IOException e) {
				e.printStackTrace();
			} finally {
				try {
					br.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
			
		}
	}
	public static long getOneMonthAgo(Date now) {
		// 获取一个月前的时间
		Calendar dataCalculate = Calendar.getInstance();
		dataCalculate.setTime(now);
		// 减掉一个月
		dataCalculate.add(Calendar.MONTH, -1);
		// 获取一个月前的时间
		Date oneMonthAgo = dataCalculate.getTime();
		long oneMonthAgoLong = oneMonthAgo.getTime();
		return oneMonthAgoLong;
	}
}
